#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <openssl/pem.h>
#include <openssl/err.h>

// 将DER编码数据进行Base64编码
char* base64_encode_der(const unsigned char* der_data, int der_length)
{
    BIO *bio, *b64;
    BUF_MEM *bufferPtr = NULL;
    char *base64_data;

    // 创建一个BIO对象，将输出数据存放到内存中
    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);

    // 在BIO对象中写入DER编码数据
    BIO_write(bio, der_data, der_length);
    BIO_flush(bio);

    // 获取输出的Base64编码数据
    BIO_get_mem_ptr(bio, &bufferPtr);
    base64_data = (char*)malloc(bufferPtr->length + 1);
    memcpy(base64_data, bufferPtr->data, bufferPtr->length);
    base64_data[bufferPtr->length] = '\0';

    // 释放资源
    BIO_free_all(bio);

    return base64_data;
}


// 生成一个ASN.1结构体，其中包含一个整数值
ASN1_INTEGER* create_asn1_integer(int value)
{
    ASN1_INTEGER* integer;

    integer = ASN1_INTEGER_new();
    if (!integer)
    {
        return NULL;
    }

    if (!ASN1_INTEGER_set(integer, value))
    {
        ASN1_INTEGER_free(integer);
        return NULL;
    }

    return integer;
}

// 将ASN.1结构体编码为DER格式，并返回DER编码数据的指针和长度
int encode_asn1_der(ASN1_TYPE* type, unsigned char** out_data)
{
    unsigned char *p, *out;
    int len, out_len;

    len = i2d_ASN1_TYPE(type, NULL);
    out = (unsigned char*)malloc(len);
    if (!out)
    {
        return -1;
    }

    p = out;
    i2d_ASN1_TYPE(type, &p);

    *out_data = out;
    out_len = len;

    return out_len;
}

int main()
{
    ASN1_TYPE* type;
    ASN1_INTEGER* integer;
    unsigned char *der_data;
    int der_len;

    // 创建ASN.1结构体
    type = ASN1_TYPE_new();
    if (!type)
    {
        return -1;
    }

    integer = create_asn1_integer(2022);
    if (!integer)
    {
        ASN1_TYPE_free(type);
        return -1;
    }

    ASN1_TYPE_set_octetstring(type, (unsigned char*)integer, sizeof(ASN1_INTEGER));

    // 将ASN.1结构体编码为DER格式
    der_len = encode_asn1_der(type, &der_data);
    if (der_len < 0)
    {
        ASN1_INTEGER_free(integer);
        ASN1_TYPE_free(type);
        return -1;
    }

    // 对DER编码数据进行Base64编码
    char* base64_data = base64_encode_der(der_data, der_len);

    // 打印Base64编码数据
    printf("Base64-encoded DER data: %s", base64_data);

    // 释放资源
    free(der_data);
    ASN1_INTEGER_free(integer);
    ASN1_TYPE_free(type);
    free(base64_data);

    return 0;
}
